# ----------------------------------------------------------------------------
# pytform
# Copyright (c) 2008, Michael Henrique Siegwarth
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions 
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above copyright 
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
#  * Neither the name of pytform nor the names of its
#    contributors may be used to endorse or promote products
#    derived from this software without specific prior written
#    permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# ----------------------------------------------------------------------------

from math import degrees

import Box2D2 as box2d
import pyglet.gl
from pyglet.window import key

import base.game_object

class PlayerObject(base.game_object.GameObject):
    def __init__(self, x, y, angle, world, batch):
        super(PlayerObject, self).__init__(x, y, angle, True, world)

        shape_def = box2d.b2PolygonDef()
        shape_def.SetAsBox(0.4, 0.8)
        shape_def.density = 1
        shape_def.friction = 0.9
        shape_def.restitution = 0
        
        self.body.CreateShape(shape_def).getAsType()
        self.body.SetMassFromShapes()

        # Create vertex list
        self.vertex_list.append(batch.add(4, pyglet.gl.GL_QUADS, None,
            'v2f',
            ('c4f', (0, 0.5, 0, 0.5,
                     0.5, 0, 0.5, 0.5,
                     0, 0, 0.5, 0.5,
                     0, 0, 0, 0.5))
        ))

        shape_def = box2d.b2PolygonDef()
        shape_def.isSensor = True

        shape_def.vertexCount = 4
        shape_def.setVertex(0, 0.4, -0.8)
        shape_def.setVertex(1, 0.4, -0.7)
        shape_def.setVertex(2, -0.4, -0.7)
        shape_def.setVertex(3, -0.4, -0.8)
        
        self.ground_checker = self.body.CreateShape(shape_def).asPolygon()

        # Create vertex list
        self.vertex_list.append(batch.add(4, pyglet.gl.GL_QUADS, None,
            'v2f',
            ('c4f', (0, 0, 0, 0.1,
                     0, 0, 0, 0.1,
                     0, 0, 0, 0.1,
                     0, 0, 0, 0.1))
        ))

        self.update_vertices()

        self.body.SetMassFromShapes()

        self.keys = dict()
        self.id = 1

        self.jump_counter = 0
        self.touching_terrain = False
        self.move_strength = 2

        self.events.append(["a", "triangle.TerrainTriangle", self.may_jump])
        self.events.append(["r", "triangle.TerrainTriangle", self.may_not_jump])

    def may_jump(self, trigger_object, source_shape, trigger_shape, normal):
        if source_shape == self.ground_checker:
            self.jump_counter += 1
        else:
            self.touching_terrain = True

    def may_not_jump(self, trigger_object, source_shape, trigger_shape, normal):
        if source_shape == self.ground_checker:
            self.jump_counter -= 1
        else:
            self.touching_terrain = False
            print normal

    def step(self):
        if self.keys[key.I]:
            self.jump()
        if self.keys[key.J]:
            self.move_left()
        if self.keys[key.L]:
            self.move_right()

    def jump(self):
        if self.jump_counter > 0:
            vy = self.body.GetLinearVelocity().y
            if vy < 6:
                self.body.ApplyImpulse(box2d.b2Vec2(0, 6 - vy),
                                       box2d.b2Vec2(self.body.GetPosition().x, 
                                                    self.body.GetPosition().y))

    def move_left(self):
        if self.jump_counter != 0 or self.touching_terrain == False:
            v = self.body.GetLinearVelocity()

            if v.x >= 0 or v.Length() < 6:
                self.body.ApplyImpulse(box2d.b2Vec2(-self.move_strength, 0),
                                       box2d.b2Vec2(self.body.GetPosition().x, 
                                                    self.body.GetPosition().y))

    def move_right(self):
        if self.jump_counter != 0 or self.touching_terrain == False:
            v = self.body.GetLinearVelocity()
            vl = v.Length()

            if v.x < 0 or v.Length() < 6:
                self.body.ApplyImpulse(box2d.b2Vec2(self.move_strength, 0),
                                       box2d.b2Vec2(self.body.GetPosition().x, 
                                                    self.body.GetPosition().y))

